/*
 * CompareMetric.cpp
 *
 *  Created on: 13-09-2013
 *      Author: Krzychu
 */

#include <ctype.h>
#include <sstream>
#include <algorithm>

#include "CompareMetric.h"
#include "Utils/QuickSort.h"

CompareMetric::CompareMetric()
{
	// polish letters
	desiredCharacterCodes.push_back(206);
	desiredCharacterCodes.push_back(210);
	desiredCharacterCodes.push_back(230);
	desiredCharacterCodes.push_back(242);
	desiredCharacterCodes.push_back(245);
	desiredCharacterCodes.push_back(251);
	desiredCharacterCodes.push_back(253);
	desiredCharacterCodes.push_back(276);
	desiredCharacterCodes.push_back(344);
}

CompareMetric::~CompareMetric()
{

}

void CompareMetric::clean(string& word)
{
	for (int i = 0; i < word.length(); i++)
	{
		if (/*!find(desiredCharacterCodes.begin(), desiredCharacterCodes.end(), (int)word[i]) && */!isalnum(word[i]))
		{
			word.erase(i--, 1);
		}
	}
}

void CompareMetric::addWord(string word)
{
	documentWordsCount++;
	documentLength += word.size();

	clean(word);

	if (word.size() > 1) // 1-char words are insignificant
	{
		words.push_back(word);

		map<string, int>::iterator it = wordsCount.find(word);

		if (it != wordsCount.end())
		{
			wordsCount.at(word) = wordsCount.at(word) + 1;
		}
		else
		{
			wordsCount.insert(pair<string, int>(word, 1));
		}
	}
}

void CompareMetric::sortWordCounts()
{
	vector<int> countsVector;
	for (map<string, int>::iterator it = wordsCount.begin(); it != wordsCount.end(); ++it)
	{
		countsVector.push_back(it->second);
	}

	QuickSort::sort(countsVector);

	map<string, int> newWordsCount;
	map<string, int>::iterator newMapIt = newWordsCount.begin();

	for (int i = 0; i < countsVector.size(); i++)
	{
		for (map<string, int>::iterator it = wordsCount.begin(); it != wordsCount.end(); ++it)
		{
			if (countsVector[i] == it->second)
			{
				newWordsCount.insert(newMapIt++, pair<string, int>(it->first, it->second));
			}
		}
	}

	wordsCount = newWordsCount;
}


void CompareMetric::generateNWords(int maxFragmentCount)
{
	int wordsLimit = maxFragmentCount <= words.size() ? maxFragmentCount : words.size();

	for (int i = 2; i < wordsLimit; i++)
	{
		pair<int, vector<string> > entry;
		entry.first = i;
		vector<string> entryNWords;

		for (int j = 0; j < words.size() - i + 1; j++)
		{
			ostringstream nWord;

			for (int k = 0; k < i; k++)
			{
				nWord << words[j + k];
			}

			entryNWords.push_back(nWord.str());
		}

		entry.second = entryNWords;

		nWords.insert(entry);
	}
}

map<string, int> CompareMetric::getWordsCount()
{
	return wordsCount;
}

int CompareMetric::getWordCount(string word)
{
	return wordsCount.at(word);
}

map<int, vector<string> > CompareMetric::getNWords()
{
	return nWords;
}

vector<string> CompareMetric::getWords()
{
	return words;
}
